package boot;

import javax.persistence.EntityManager;
import javax.servlet.DispatcherType;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.embedded.ConfigurableEmbeddedServletContainer;
import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.support.SpringBootServletInitializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.ImportResource;
import org.springframework.web.servlet.ModelAndView;

import net.gazhi.delonix.core.init.InitExecuter;
import net.gazhi.delonix.core.jpa.Dao;
import net.gazhi.delonix.core.thread.ResetThreadContextFilter;
import net.gazhi.delonix.core.web.ErrorPages;
import net.gazhi.delonix.rbac.RBACConfigure;
import net.gazhi.delonix.rbac.web.controller.IndexHandler;

/**
 * 应用启动入口类
 * 
 * @author jeffreylin@gazhi.net
 *
 */
@SpringBootApplication
@ImportResource("classpath:spring.xml")
@Import(value = { RBACConfigure.class })
public class DelonixWebApp extends SpringBootServletInitializer {

	/**
	 * main 入口函数
	 * 
	 * @param args
	 * @throws Exception
	 */
	public static void main(String[] args) throws Exception {
		SpringApplication.run(DelonixWebApp.class, args);
	}

	/**
	 * 加载 spring 配置
	 */
	@Override
	protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
		return application.sources(DelonixWebApp.class);
	}

	/**
	 * 注册过滤器：resetThreadContextFilter
	 * 
	 * @return
	 */
	@Bean
	public FilterRegistrationBean resetThreadContextFilterRegistration() {
		FilterRegistrationBean registration = new FilterRegistrationBean(new ResetThreadContextFilter());
		registration.setDispatcherTypes(DispatcherType.REQUEST);
		return registration;
	}

	/**
	 * 设置错误页面
	 * 
	 * @return
	 */
	@Bean
	public EmbeddedServletContainerCustomizer containerCustomizer() {
		return new EmbeddedServletContainerCustomizer() {
			@Override
			public void customize(ConfigurableEmbeddedServletContainer container) {
				container.addErrorPages(ErrorPages.PAGES);
			}
		};
	}

	/**
	 * 应用初始化执行器
	 * 
	 * @return
	 */
	@Bean
	public InitExecuter initExecuter() {
		return new InitExecuter();
	}

	/**
	 * Hibernate 数据访问 dao
	 * 
	 * @param entityManager
	 * @return
	 */
	@Bean
	public Dao dao(EntityManager entityManager) {
		return new Dao(entityManager);
	}

	/**
	 * 可替代的首页处理器：indexHandler
	 * 
	 * @return
	 */
	@Bean
	@ConditionalOnMissingBean
	public IndexHandler indexHandler() {
		return new IndexHandler() {
			@Override
			public ModelAndView index() {
				return new ModelAndView("index");
			}
		};
	}

}
